Function configurations (memory, timeout, concurrency)
Function code (layers, env vars, idempotency)
Versions and aliases
Running and testing functions
Lambda error handling (sync, async, polling)
Lambda Runs in Ephemeral Environments
Analogy: Food truck. It parks (INIT), serves customers (INVOKE), and if idle too long, drives away (SHUTDOWN). Next customer = new truck or reuse the parked one.
Lambda may create a new "cold" environment or reuse a "warm" one
Lambda Best Practices (Lifecycle)
Take advantage of environment reuse - init outside handler
Wait for background processes and callbacks to complete
Manage DB connection pooling with RDS Proxy
Persist state data externally (DynamoDB, S3, ElastiCache, EFS)
Minimize deployment package size and dependency complexity
Mount Amazon EFS for large or shared assets
Use Provisioned Concurrency to avoid cold starts
Pre-heat the oven (INIT) once, then cook many dishes (handler invocations). Don't restart the oven for every order.
Environment Reuse: Initialize Outside Handler
// Declare DynamoDB client OUTSIDE handler - runs once during INIT
const AWS = require("aws-sdk");
var ddbClient = new AWS.DynamoDB();
const tableName = process.env.SAMPLE_TABLE; // From env vars
exports.putItemHandler = async (event) => {
// Handler runs every invocation - keep it lean
const { body, httpMethod, path } = event;
if (httpMethod !== 'POST') {
throw new Error(`postMethod only accepts POST`);
}
// Use pre-initialized ddbClient...
};
Park your car once (INIT), then make multiple trips inside the building (handler). Don't re-park for every trip.
Environment Reuse: /tmp as Transient Cache
const fs = require('fs');
const s3 = new AWS.S3();
exports.handler = async (event) => {
let config;
try {
// Try loading from /tmp (warm invocation - instant!)
config = fs.readFileSync('/tmp/config.json');
} catch (e) {
// Cold start - download from S3, save to /tmp
let data = await s3.getObject({Bucket:'mybucket', Key:'config.json'}).promise();
config = data.Body.toString('utf8');
fs.writeFileSync('/tmp/config.json', config);
}
return config;
};
/tmp provides up to 10GB of ephemeral storage that persists across warm invocations.
Database Connection Pooling with RDS Proxy
Without proxy: Every Lambda opens its own connection (like every guest bringing their own waiter). With proxy: One shared pool (one team of waiters serves everyone).
Writes code autonomously, generates implementations from specs
Test & Secure
Runs builds, validates changes, checks for errors automatically
Operate
Hooks for automation, MCP integrations, infrastructure management
Maintain
Steering files for standards, context-aware refactoring
Kiro = your AI development partner. It reads your codebase, understands your architecture, writes code, runs tests, and deploys - all guided by structured specs or free-form conversation.
Versions and Aliases
Publish creates an immutable version (snapshot of code + config)
Aliases point to a version; shift traffic between two versions (canary)
Lambda Error Handling - Two Types
Error Handling Differs by Event Source
Source Type
Who Handles Errors
Retry Behavior
Synchronous
CLIENT handles all errors
Client must implement retries
Asynchronous
Lambda shares handling
0-2 retries + retry invoke up to 6 hours. Then: DLQ or OnFailure destination
Polling (SQS)
Lambda manages
Batch fails = messages become visible again. Partial batch response to report individual failures.
Polling (Streams)
Lambda manages
Blocks shard until success or expiry. Options: bisect batch, max retries, checkpointing.
Restaurant analogy: Sync = customer waits at counter (they deal with mistakes). Async = order submitted, kitchen retries if burned. Polling = buffet attendant keeps refilling until tray is done.
Error Handling: SQS Queues
Best practice: Use ReportBatchItemFailures - only failed messages retry, successful ones are deleted. Set max receives on DLQ to limit retries.
Error Handling: Streams (Kinesis/DDB)
BisectBatchOnFunctionError - Split failed batch in half, retry each half to isolate bad record
MaximumRetryAttempts - Limit retries instead of blocking forever
Checkpointing - Report last successfully processed record; only retry from that point
OnFailure Destination - Send failed records to SQS/SNS for investigation
Assembly line analogy: Bisect = split the batch to find the defective item. Checkpointing = mark where you stopped so you don't redo finished work. DLQ = rejection bin for investigation.
Kiro - AI-powered IDE for spec-driven development, code generation, and automation
Q1: Where should you initialize your DynamoDB client?
B) Outside handler - Runs during INIT, reused across warm invocations. A: Creates new client every call (wasteful). C: Adds latency. D: Env vars store strings, not objects.
Q2: Async Lambda fails. Default behavior?
B) 0-2 retries then discard. Use DLQ/destination to capture. A: Not immediate - retries first. C: That's streams. D: Async returns 202, caller never sees errors.
Q3: What problem does RDS Proxy solve for Lambda?
B) Connection pooling. High Lambda concurrency can exhaust DB connections. Proxy pools them. A: Provisioned Concurrency solves cold starts. C: TLS does that. D: Memory is configured separately.
Q4: What does BisectBatchOnFunctionError do for streams?
A) Splits batch in half. Recursively bisects until isolating the poison record, then sends to OnFailure destination. B: That skips good records. C: Data loss. D: Makes problem worse.
Module Summary
Best practices reflect the ephemeral nature of Lambda lifecycle
Your function includes configuration options as well as code
Versions and aliases simplify modifications to your application
You can test functions from the console or SAM CLI locally
Error handling differs by event source type (sync/async/polling)
Use RDS Proxy for connection pooling, EFS for large assets
Kiro supports you across the entire SDLC with specs, hooks, and MCP